06. 关于 OOP 的几个注意事项
关于 OOP 的注意事项
关于 OOP 的注意事项
Set 和 Get 方法
上一部分的视频提到在 Python 里访问属性与在 Java 和 C++ 等其他语言中不太一样。这部分将深入介绍这方面的知识。
shirt 类有一个更改衬衫价格的方法:
shirt_one.change_price(20)
。在 Python 里,你还可以通过以下语法更改属性的值:
shirt_one.price = 10
shirt_one.price = 20
shirt_one.color = 'red'
shirt_one.size = 'M'
shirt_one.style = 'long_sleeve'
这段代码会直接访问并更改 price、color、size 和 style 属性。很多其他语言在使用时,都不推荐或者禁用直接访问属性, 但是 Python 允许直接访问属性 。常用面向对象编程规范是使用方法访问属性或更改属性值。这些方法称为 set 和 get 方法或 setter 和 getter 方法。
get 方法用于获取属性值。set 方法用于更改属性值。对于 Shirt 类来说,代码如下所示:
class Shirt:
def __init__(self, shirt_color, shirt_size, shirt_style, shirt_price):
self._price = shirt_price
def get_price(self):
return self._price
def set_price(self, new_price):
self._price = new_price
实例化和使用对象如下所示:
shirt_one = Shirt('yellow', 'M', 'long-sleeve', 15)
print(shirt_one.get_price())
shirt_one.set_price(10)
在类定义里,price 前面的下划线是比较有争议的 Python 规范。在 C++ 或 Java 等其他语言里,price 会被明确标记为私有变量,禁止对象直接访问 price 属性,所以
shirt_one._price = 15
也就不可行。但是,Python 不像其他语言那样区分公共变量和私有变量。因此,在 Python 中使用下划线规范和 get 及 set 方法就有一定的争议。
但是,很多 Python 程序员还是会使用 get 和 set 方法开发面向对象程序。如果 Python 本身并不鼓励使用 get 和 set 方法,为何还要使用它们?
根据 Python 规范,price 前面的下划线是告诉程序员只能通过 get 和 set 方法访问 price,而不能使用
shirt_one._price
直接访问 price。但是,程序员依然可以直接访问 price,因为 Python 语言并没有禁止直接访问属性。
重申下,技术上来说,程序员依然可以使用
shirt_one._price = 10
这样的直接访问,代码能运行。但是像这样直接访问 price 并不符合 Shirt 类的设计意图和使用规范。
正如之前在这门课程中提到的,set 和 get 方法的优势之一是可以向用户隐藏实现代码。也许变量一开始编写为列表,之后变成了字典。借助 set 和 get 方法,你可以轻松地更改获取该变量的方式。如果没有 set 和 get 方法,你需要找到直接访问该变量的所有代码并更改代码。
要详细了解 Python 中的 set 和 get 方法,请访问此 Python 教程网站 。
关于属性的注意事项
与使用方法访问属性相比,直接访问属性有很多劣势。
对于面向对象编程来说,Python 的编写规范比其他编程语言要宽松。例如之前提到的,在 C++ 等语言中,你可以明确设置禁止直接更改或访问属性值。Python 就没有这样的设定。
那么,为何通过方法更改值比直接更改值更好?因为,从长远来看,通过方法更改值能使代码更灵活。比如,如果计量单位变了,该怎么办?假设某商店的售卖商品一开始采用的是美元货币,现在需要采用欧元?举个例子:
美元与欧元换算示例
如果直接更改属性值,你就需要找到所有使用美元的代码,例如:
shirt_one.price = 10 # US dollars
然后手动换算并修改为欧元
shirt_one.price = 8 # Euros
但是,如果你使用了方法,则只需更改方法,自动从美元换算成欧元。
def change_price(self, new_price):
self.price = new_price * 0.81 # convert dollars to Euros
shirt_one.change_price(10)
如果你刚开始学习面向对象编程,你可能还不会涉及到这个方面,但是,如果你决定深入学习,尤其是 C++ 或 Java 等其他语言,这个方面的考量对你的代码编写就会显得非常重要。
模块化代码
所有代码都在 Jupyter Notebook 里,例如,在之前的练习中,有个加载 Shirt 类的代码单元格,让你能够在整个 notebook 的后续部分访问 Shirt 类。但是,如果你要开发软件程序,则需要模块化代码。
你需要将 Shirt 类放入单独的 Python 脚本中,并取个名称,例如 shirt.py。然后在另一个 Python 脚本里,使用以下这行代码导入 Shirt 类:
from shirt import Shirt
.
目前你可以在 Jupyter notebook 中完成练习。但是之后你需要学会将面向对象代码模块化为单独的文件。